#include <QMetaObject>
#include <QMetaProperty>
#include "oxford-word-usage-variant.h"
#include "json-serializator.h"
#include "json-deserializator.h"
#include "serializator.h"
#include "deserialization-error.h"

using namespace Oxford;

bool WordUsageVariant::isValid() const
{
    return true;
}

ObjectString WordUsageVariant::toString() const
{
    Core::JSONSerializator serializator;

    serializator.beginObject();

    serializator.writeProperty("wordUsage", _wordUsage);
    serializator.writeProperty("usageRule", _usageRule);
    serializator.writeProperty("synonym", _synonym);

    serializator.beginList("examples");
    for (int i = 0; i < _examples.count(); i++)
        serializator.writeListItem(QVariant::fromValue(_examples[i].toString()));
    serializator.endList();

    serializator.endObject();

    return serializator.result();
}

WordUsageVariant WordUsageVariant::fromString(QString data)
{
    Core::JSONDeserializator deserializator(data);

    WordUsageVariant result;
    const QMetaObject* meta = result.metaObject();
    try
    {
        deserializator.beginObject();

        while (!deserializator.atEnd())
        {
            QString propertyName = deserializator.readPropertyName();
            int propertyId = meta->indexOfProperty(propertyName.toStdString().c_str());

            if (propertyId < 0)
                continue;

            Core::IDeserializator::PropertyType propertyType = deserializator.readPropertyType();

            switch (propertyType)
            {
            case Core::IDeserializator::Variant:
                meta->property(propertyId).write(&result, deserializator.readPropertyValue());
                break;

            case Core::IDeserializator::Object:
                break;

            case Core::IDeserializator::List:
                QVariantList list = deserializator.readPropertyValue().toList();

                if (propertyName == "examples")
                {
                    QList<WordUsageExample> examples;

                    foreach (const QVariant& example, list)
                        examples << WordUsageExample::fromString(example.toString());

                    result._examples = examples;
                }
                break;
            }
        }

        deserializator.endObject();
        return result;
    }
    catch (Core::EDeserializationError)
    {

    }
    catch (...)
    {

    }

    return WordUsageVariant();

}
